package IterableIterator;

import TDALista.BoundaryViolationException;
import TDALista.DoubleLinkedList;
import TDALista.EmptyListException;
import TDALista.InvalidPositionException;
import TDALista.Position;
import TDALista.PositionList;

/**
 * Clase que encapsula dos métodos para eliminar los elementos pares de una lista de valores enteros.</br>
 * Los métodos se distinguen por la forma en la que se recorren las listas a modificar:
 * <ul>
 * <li> <i>Con recorrido "manual"</i>: se utilizan los métodos first(), last(), next() de la lista.</li>
 * <li> <i>Con método positions()</i>: se utiliza la instrucción for-each y el iterable de posiciones retornado por el método positions() de lista.</li>
 * </ul> </br>
 * 
 * <b>Requiere:</b> <i>TDALista2</i>.
 * @author FJoaquin (federico.joaquin@cs.uns.edu.ar)
 */
public class EjerciciosSobreLista{
	
	/**
	 * Elimina los números pares de una lista, recorriéndola de forma "manual".
	 * @param l Lista a modificar, eliminándole los números pares.
	 */
	public static void eliminar_con_recorrido_manual(PositionList<Integer> l){
		int elemento;
		try{
			Position<Integer> actual = l.isEmpty() ? null : l.first();
			Position<Integer> aux;
			while(actual != null && actual != l.last()){
				elemento = actual.element();
				aux = l.next(actual);
				if (elemento % 2 == 0){
					l.remove(actual);
				}
				actual = aux;
			}
			if (actual != null){
				if (actual.element() % 2 == 0)
					l.remove(actual);
			}
		}catch(EmptyListException e){
		}catch(InvalidPositionException e1){
		}catch(BoundaryViolationException e2){
		}
	}
	
	/**
	 * Elimina los números pares de una lista, recorriéndola mediante el uso de un iterable de posiciones.
	 * @param l Lista a modificar, eliminándole los números pares.
	 */
	public static void eliminar_con_positions(PositionList<Integer> l){
		try{
			for(Position<Integer> pos : l.positions()){
				if (pos.element() % 2 == 0)
					l.remove(pos);
			}
		}catch(InvalidPositionException e){}
	}
	
	/**
	 * Método que inicia la ejecución del programa. Testea el funcionamiento de <i>eliminar_con_recorrido_manual</i> y <i>eliminar_con_positions</i> con dos listas prueba.
	 * @param args Argumentos por línea de comandos.
	 */
	public static void main(String [] args){
		PositionList<Integer> l1 = new DoubleLinkedList<Integer>();
		PositionList<Integer> l2 = new DoubleLinkedList<Integer>();
		
		//Inicializa L1 con elementos enteros en el rango [20-40]
		//Inicializa L2 con elementos enteros en el rango [50-70]
		for(int i=0; i<=20; i++) {
			l1.addLast(20 + i);
			l2.addLast(50 + i);
		}
				
		//Muestra el contenido de L1 y L2 haciendo uso de dos iteradores.
		System.out.println("Elementos de L1 antes de eliminar:");
		for(Integer i : l1) System.out.print(i + " - ");
		System.out.println("\nElementos de L2 antes de eliminar:");
		for(Integer i : l2) System.out.print(i + " - ");
		
		//Elimina los elementos pares de L1 y L2.
		eliminar_con_recorrido_manual(l1);
		eliminar_con_positions(l2);
		
		//Muestra el contenido de L1 y L2 haciendo uso de dos iteradores.
		System.out.println("\nElementos de L1 luego de eliminar:");
		for(Integer i : l1) System.out.print(i + " - ");
		System.out.println("\nElementos de L2 luego de eliminar:");
		for(Integer i : l2) System.out.print(i + " - ");
	}
}
